package net.chasing.androidbaseconfig.util.glide.base;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import androidx.annotation.NonNull;

import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation;

import java.security.MessageDigest;

/**
 * Glide加载圆角图片/Gif
 * 使用：    .transform(new CenterCrop(context), new GlideRoundTransform(context, 10))
 * 注： 对error和placeHolder没有作用，只有请求成功才会进行裁剪，所以默认图及失败图本身需要包含圆角及边框
 * error可通过监听listener，失败之后进行Glide加载带入GlideRoundTransform展示圆角及边框
 * placeHolder则只能默认图本身就带有圆角及边框（建议使用thumbnail代替placeHolder）
 */
public class GlideRoundTransform extends BitmapTransformation {
    private static final String ID = "net.chasing.androidbaseconfig.util.glide.base.GlideRoundTransform";
    private static final byte[] ID_BYTES = ID.getBytes(CHARSET);

    private Paint mBorderPaint;
    private float borderSize;
    private final float radius;
    // 如果图片的宽高不能铺满UI，是否进行隐藏图片的圆角
    private boolean hideRadiusWhenNoMatch;
    private int mBackgroundColor;

    private boolean isLeftTop = true, isLeftBottom = true, isRightTop = true, isRightBottom = true;

    /**
     * 构造函数
     *
     * @param dp 圆角半径
     */
    public GlideRoundTransform(int dp) {
        radius = Math.round(Resources.getSystem().getDisplayMetrics().density * (dp + 0.5));
    }

    public GlideRoundTransform(int dp, float borderSize, int borderColor) {
        radius = Math.round(Resources.getSystem().getDisplayMetrics().density * (dp + 0.5));
        if (borderSize > 0) {
            this.borderSize = borderSize;
            mBorderPaint = new Paint();
            mBorderPaint.setColor(borderColor);
            mBorderPaint.setStyle(Paint.Style.STROKE);
            mBorderPaint.setAntiAlias(true);
            mBorderPaint.setStrokeWidth(borderSize);
            mBorderPaint.setDither(true);
        }
    }

    public GlideRoundTransform setBackgroundColor(int backgroundColor) {
        mBackgroundColor = backgroundColor;
        return this;
    }

    public GlideRoundTransform setHideRadiusWhenNoMatch(boolean hideRadiusWhenNoMatch) {
        this.hideRadiusWhenNoMatch = hideRadiusWhenNoMatch;
        return this;
    }

    public GlideRoundTransform setLeftTop(boolean leftTop) {
        isLeftTop = leftTop;
        return this;
    }

    public GlideRoundTransform setLeftBottom(boolean leftBottom) {
        isLeftBottom = leftBottom;
        return this;
    }

    public GlideRoundTransform setRightTop(boolean rightTop) {
        isRightTop = rightTop;
        return this;
    }

    public GlideRoundTransform setRightBottom(boolean rightBottom) {
        isRightBottom = rightBottom;
        return this;
    }

    public GlideRoundTransform setCircleCorner(boolean isLeftTop, boolean isRightTop, boolean isLeftBottom, boolean isRightBottom) {
        this.isLeftTop = isLeftTop;
        this.isRightTop = isRightTop;
        this.isLeftBottom = isLeftBottom;
        this.isRightBottom = isRightBottom;
        return this;
    }

    @Override
    protected Bitmap transform(@androidx.annotation.NonNull BitmapPool pool, @androidx.annotation.NonNull Bitmap toTransform, int outWidth, int outHeight) {
        return roundCrop(pool, toTransform, outWidth, outHeight);
    }

    private Bitmap roundCrop(BitmapPool pool, Bitmap source, int outWidth, int outHeight) {
        if (source == null) return null;

        Bitmap result = pool.get(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);

        Canvas canvas = new Canvas(result);
        Paint paint;
        RectF rectF;
        //先画背景
        if (mBackgroundColor > 0) {
            paint = new Paint();
            paint.setColor(mBackgroundColor);
            paint.setAntiAlias(true);
            rectF = new RectF(0, 0, outWidth, outHeight);
            if (radius > 0)
                canvas.drawRoundRect(rectF, radius, radius, paint);
            else
                canvas.drawRect(rectF, paint);
        }

        //再判断画圆角图片
        paint = new Paint();
        paint.setShader(new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
        paint.setAntiAlias(true);
        rectF = new RectF(borderSize, borderSize, result.getWidth() - borderSize, result.getHeight() - borderSize);
        if (Math.abs(result.getWidth() / (float) result.getHeight() - outWidth / (float) outHeight) > 0.01 && hideRadiusWhenNoMatch)
            canvas.drawRect(rectF, paint);
        else
            canvas.drawRoundRect(rectF, radius, radius, paint);

        //判断四个角，如果取消圆角，则对圆角进行补齐成直角
        //左上角圆角
        if (!isLeftTop) {
            canvas.drawRect(0, 0, radius, radius, paint);
        }
        //右上角圆角
        if (!isRightTop) {
            canvas.drawRect(canvas.getWidth() - radius, 0, canvas.getWidth(), radius, paint);
        }
        //左下角圆角
        if (!isLeftBottom) {
            canvas.drawRect(0, canvas.getHeight() - radius, radius, canvas.getHeight(), paint);
        }
        //右下角圆角
        if (!isRightBottom) {
            canvas.drawRect(canvas.getWidth() - radius, canvas.getHeight() - radius, canvas.getWidth(), canvas.getHeight(), paint);
        }

        //描边,画边框
        if (borderSize > 0) {
            rectF = new RectF(0 + borderSize / 2, 0 + borderSize / 2,
                    result.getWidth() - borderSize / 2, result.getHeight() - borderSize / 2);
            canvas.drawRoundRect(rectF, radius, radius, mBorderPaint);
        }
        return result;
    }

    @Override
    public void updateDiskCacheKey(@NonNull MessageDigest messageDigest) {
        messageDigest.update(ID_BYTES);
    }
}